#include "manano_common.h"

#include "mdtx-online/indicator/indicator_type_s2_band.h"
namespace indi = mdtx::online::indicator;

using bband = unary2<indi::bband>;
using band_ew = unary2<indi::band_ew>;
using band_cu = unary2<indi::band_cu>;
using band_vw = binary2<indi::band_vw>;
using band_cuvw = binary2<indi::band_cuvw>;

using band_sz = unary2<indi::band_sz>;
using band_szew = unary2<indi::band_szew>;
using band_szcu = unary2<indi::band_szcu>;

void bind_indi_s2_band(py::module &m)
{
    auto mod = m.def_submodule("band", "Band indicators");
    {
        auto v = py::class_<bband>(mod, "boll")
                     .def(py::init<int, double>(), py::arg("period"), py::arg("z"))
                     .def("run", &bband::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &bband::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Bollinger bands
                    Args:
                        period (int) : rolling window period
                        z (float64) : threshold zscore)mydoc";
    }
    {
        auto v = py::class_<band_ew>(mod, "band_ew")
                     .def(py::init<int, double>(), py::arg("period"), py::arg("z"))
                     .def("run", &band_ew::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_ew::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Exponentially weighed rolling var bands
                    Args:
                        period (int) : rolling window period
                        z (float64) : threshold zscore)mydoc";
    }
    {
        auto v = py::class_<band_cu>(mod, "band_cu")
                     .def(py::init<double>(), py::arg("z"))
                     .def("run", &band_cu::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_cu::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Cumulative var bands
                    Args:
                        z (float64) : threshold zscore)mydoc";
    }
    {
        auto v = py::class_<band_vw>(mod, "band_vw")
                     .def(py::init<int, double>(), py::arg("period"), py::arg("z"))
                     .def("run", &band_vw::run, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                           w (float64) : volume (weight)
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_vw::run2, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                           w (numpy.array) : volume (weight)
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Volume weighted rolling var bands
                    Args:
                        period (int) : rolling window period
                        z (float64) : threshold zscore)mydoc";
    }
    {
        auto v = py::class_<band_cuvw>(mod, "band_cuvw")
                     .def(py::init<double>(), py::arg("z"))
                     .def("run", &band_cuvw::run, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                           w (float64) : volume (weight)
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_cuvw::run2, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                           w (numpy.array) : volume (weight)
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Cumulative volume weighted var bands
                    Args:
                        z (float64) : threshold zscore)mydoc";
    }
    {
        auto v = py::class_<band_sz>(mod, "band_sz")
                     .def(py::init<int, double, double>(), py::arg("period"), py::arg("z"), py::arg("r"))
                     .def("run", &band_sz::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_sz::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Smoothed rolling zscore bands
                    Args:
                        period (int) : rolling window period
                        z (float64) : threshold zscore
                        r (float64) : attenuation factor)mydoc";
    }
    {
        auto v = py::class_<band_szew>(mod, "band_szew")
                     .def(py::init<int, double, double>(), py::arg("period"), py::arg("z"), py::arg("r"))
                     .def("run", &band_szew::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           upper band (float64)
                           lower band (float64))mydoc")
                     .def("run", &band_szew::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                          upper band (numpy.array)
                          lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Exponentially weighted smoothed rolling zscore bands
                    Args:
                        period (int) : rolling window period
                        z (float64) : threshold zscore
                        r (float64) : attenuation factor)mydoc";
    }
    {
        auto v = py::class_<band_szcu>(mod, "band_szcu")
                     .def(py::init<double, double>(), py::arg("z"), py::arg("r"))
                     .def("run", &band_szcu::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                          x (float64) : input data
                        Return:
                          upper band (float64)
                          lower band (float64))mydoc")
                     .def("run", &band_szcu::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           upper band (numpy.array)
                           lower band (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Cumulative smoothed zscore bands
                    Args:
                        z (float64) : threshold zscore
                        r (float64) : attenuation factor)mydoc";
    }
}
